package com.starview.star.compiler.util;

import java.io.*;
import java.util.Iterator;
import java.util.List;

/**
 * Handy file utility class for reading/writing character files. Related to this is a listener interface that will be
 * called for each line of the file.
 *
 * @author Richard
 * @version 1.0
 */
public class FileUtil{

  public static String readFile(String filename) throws IOException{
    StringBuffer buf = new StringBuffer(100);

    readFileImpl(new File(filename), buf, null, null);

    return buf.toString();
  }

  public static String readFile(File theFile) throws IOException{
    StringBuffer buffer = new StringBuffer(100);

    readFileImpl(theFile, buffer, null, null);

    return buffer.toString();
  }

  public static void readFile(File theFile, StringBuffer buffer) throws IOException{
    readFileImpl(theFile, buffer, null, null);
  }

  public static void readFile(File theFile, List<String> stringList) throws IOException{
    readFileImpl(theFile, null, stringList, null);
  }

  public static void readAFile(File theFile, FileLineListener listener) throws IOException{
    readFileImpl(theFile, null, null, listener);
  }

  public static void writeFile(File theFile, List<String> stringList) throws IOException{
    writeFileImpl(theFile, null, stringList);
  }

  public static void writeFile(File theFile, String content) throws IOException{
    writeFileImpl(theFile, content, null);
  }

  private static void readFileImpl(File theFile, StringBuffer buffer, List<String> stringList,
                                   FileLineListener listener)
          throws IOException{
    try {

      try (InputStreamReader isr = new InputStreamReader(new FileInputStream(theFile))) {
        LineNumberReader lnr = new LineNumberReader(isr);

        try {
          String line = null;

          line = lnr.readLine();

          while (line != null) {
            if (buffer != null) {
              buffer.append(line);
              buffer.append(System.getProperty("line.separator"));
            }

            if (stringList != null)
              stringList.add(line);

            if (listener != null)
              listener.onLine(line);

            line = lnr.readLine();
          }
        } finally {
          lnr.close();
        }
      }
    } catch (IOException e) {
      throw e;
    }
  }

  private static void writeFileImpl(File theFile, String content, List<String> stringList) throws IOException{
    try {
      PrintWriter writer = new PrintWriter(new FileOutputStream(theFile));

      try {
        if (content != null) {
          writer.print(content);
        } else {
          Iterator<String> itr = stringList.iterator();
          while (itr.hasNext()) {
            writer.println(itr.next());
          }
        }
      } finally {
        writer.flush();
        writer.close();
      }
    } catch (IOException e) {
      throw e;
    }
  }

  public static void rmRf(File fl){
    if (fl.isDirectory()) {
      String entries[] = fl.list();
      for (String entry : entries)
        rmRf(new File(fl, entry));
      fl.delete();
    } else if (fl.exists())
      fl.delete();
  }

  public static byte[] readFileIntoBytes(InputStream rdr) throws IOException{
    ByteBuilder buff = new ByteBuilder();

    byte[] chBuff = new byte[rdr.available()];
    for (int len = rdr.read(chBuff); len > 0; len = rdr.read(chBuff))
      buff.append(chBuff, 0, len);

    return buff.toBytes();
  }
}
